<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 点击按钮弹出警告'你别点我' -->
    <input type="button" value="click" onclick="(function(){alert('你别点我');})()" />
</body>
<script>
    //函数表达式：把函数定义直接赋值给一个变量
    let f1 = function add(){
        console.log('hello world');
    };
    //调用：变量名();
    f1();
    //带参数的函数表达式
    let f2 = function add(a,b){
        console.log(a+b);
    };
    f2(4,3);
    //有返回值的函数表达式   return
    let f3 = function add(a,b){
        return a+b;
    };
    console.log(f3(3,4));

    //匿名函数：没有函数名字
    let myf1 = function(){
        console.log('hello myf1');
    };
    myf1();
    let myf2 = function(a,b){
        return a<b?a:b;   //三元运算符
    };
    console.log(myf2(-8,0));
    //函数表达式注意的问题：一定要先声明，在调用。

    //()立即执行函数：把函数的声明看做一个整体，声明结束立即调用。匿名自调用函数
    (function(){
        console.log('hello hello');
    })();
    (function(a,b){
        console.log(a-b);
    })(44,12);
    console.log('-----------')
    console.log((function(){
        return 0;
    })());

    let a = function(){
        console.log('hello');
    };
    console.log(typeof a);   //function、数组：object
    //把函数作为参数传给另一个函数。
    //把参数A作为参数传递给函数B，并在函数B中调用函数A。把A称做回调函数。
    let arg1 = function(){
        return 0;
    };
    console.log(arg1);
    let fun = function(a,b){
        console.log(b*a());  //a() 调用函数
    };
    fun(arg1,8888);
    console.log('------------');
    //递归函数：把函数作为参数传给函数本身。
    //注意：递归函数容易造成死循环
    //阶乘：10! = 10*9*8*7...*2*1 > 10*9! > 10*9*(8!) >...10*9*8**7*6*5*4*3*2*(1!) 
    let jc = function(n){
        if(n===1){
            return 1;
        }else{
            return n*jc(n-1);
        }
    }
    console.log(jc(10));
</script>
</html>